import { useEffect, useRef } from 'react';
import { EditorState } from '@codemirror/state';
import { EditorView, keymap } from '@codemirror/view';
import { defaultKeymap, history, historyKeymap, indentWithTab } from '@codemirror/commands';
import { markdown } from '@codemirror/lang-markdown';
import { syntaxHighlighting, defaultHighlightStyle } from '@codemirror/language';
import { bracketMatching } from '@codemirror/language';
import { closeBrackets } from '@codemirror/autocomplete';
import styled from 'styled-components';
import { Toolbar } from './Toolbar';

const EditorContainer = styled.div`
  height: 100%;
  display: flex;
  flex-direction: column;
  background: white;
  border-radius: 8px;
  overflow: hidden;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
`;

const EditorContent = styled.div`
  flex: 1;
  overflow: hidden;
  position: relative;
  
  .cm-editor {
    height: 100%;
    font-size: 15px;
    color: #2f2f2f;
    background: white;
  }
  
  .cm-scroller {
    overflow: auto;
    padding: 1.5rem;
  }

  .cm-line {
    padding: 0 4px;
    line-height: 1.6;
  }

  .cm-content {
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  }

  .cm-focused {
    outline: none !important;
  }

  .cm-activeLineGutter,
  .cm-activeLine {
    background-color: #f8f9fa !important;
  }

  .cm-gutters {
    border-right: 1px solid #eee;
    background-color: #f8f9fa;
  }
`;

interface EditorProps {
  initialValue: string;
  onChange?: (value: string) => void;
}

export const Editor: React.FC<EditorProps> = ({ initialValue, onChange }) => {
  const editor = useRef<EditorView>();
  const containerRef = useRef<HTMLDivElement>(null);
  const isInitialized = useRef(false);

  useEffect(() => {
    if (!containerRef.current || isInitialized.current) return;

    const state = EditorState.create({
      doc: initialValue,
      extensions: [
        history(),
        bracketMatching(),
        closeBrackets(),
        keymap.of([...defaultKeymap, ...historyKeymap, indentWithTab]),
        markdown(),
        EditorView.lineWrapping,
        syntaxHighlighting(defaultHighlightStyle),
        EditorView.theme({
          "&": {
            height: "100%"
          },
          ".cm-editor": {
            height: "100%"
          },
          ".cm-scroller": {
            overflow: "auto",
            padding: "1rem"
          },
          ".cm-content": {
            color: "#2f2f2f",
            fontFamily: "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif",
            minHeight: "100%"
          },
          ".cm-line": {
            padding: "0 4px",
            lineHeight: "1.6"
          },
          ".cm-cursor": {
            borderLeftColor: "#000",
            borderLeftWidth: "2px"
          },
          ".cm-gutters": {
            backgroundColor: "#f8f9fa",
            border: "none",
            borderRight: "1px solid #eee"
          },
          ".cm-activeLineGutter": {
            backgroundColor: "#f0f2f5"
          },
          ".cm-activeLine": {
            backgroundColor: "#f8f9fa"
          }
        }),
        EditorView.updateListener.of((update) => {
          if (update.docChanged && onChange) {
            onChange(update.state.doc.toString());
          }
        })
      ]
    });

    editor.current = new EditorView({
      state,
      parent: containerRef.current
    });

    isInitialized.current = true;

    return () => {
      if (editor.current) {
        editor.current.destroy();
        isInitialized.current = false;
      }
    };
  }, []); // 只在挂载时初始化一次

  return (
    <EditorContainer>
      <Toolbar onInsert={(text) => {
        if (editor.current) {
          const pos = editor.current.state.selection.main.head;
          editor.current.dispatch({
            changes: { from: pos, insert: text },
            selection: { anchor: pos + text.length }  // 将光标移动到插入文本的末尾
          });
          editor.current.focus();
        }
      }} />
      <EditorContent ref={containerRef} />
    </EditorContainer>
  );
};
